<template>
  <div class="base-setting">
    <div class="setting-panel">
      <div class="panel-header">
        <p class="panel-title">作业概要</p>
      </div>

      <el-card>
        <el-form ref="task" :model="task" label-width="120px" size="mini" label-position="right">
          <el-form-item label="作业名称">
            <span>{{ task.name }}</span>
          </el-form-item>
          <el-form-item label="作业类型">
            <span>{{ task.operator }}</span>
          </el-form-item>
          <el-form-item label="Streaming 任务">
            <el-radio-group v-model="task.type" :disabled="task.operator == 'DATAFACTORY'">
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item label="失败重试次数" v-if="task.operator == 'FLINK'">
            <el-select v-model="task.retries" placeholder="请选择" clearable style="width: 100%">
              <el-option v-for="item in flinkRetryOptions" :key="item" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item label="失败重试次数" v-else>
            <el-select v-model="task.retries" placeholder="请选择" clearable style="width: 100%">
              <el-option v-for="item in [0, 1, 3, 5]" :key="item" :label="item.label" :value="item">
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item label="通知到个人邮箱">
            <el-checkbox v-model="task.email_alert"></el-checkbox>
          </el-form-item>
          <el-form-item
            label="邮箱"
            prop="email" 
            :rules="[ { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }]"
          >
            <el-input v-model="task.email" ></el-input>
          </el-form-item>
          <el-form-item label="作业描述">
            <el-input v-model="task.description"></el-input>
          </el-form-item>
          <el-form-item label="指标监控" v-if="task.operator == 'DATAFACTORY'">
            <el-switch
              v-model="isMetricsMonitor"
              active-color="#13ce66"
              inactive-color="#ff4949">
            </el-switch>
          </el-form-item>
        </el-form>
      </el-card>
    </div>
    <template v-if="needFile">
      <!-- 运行资源 -->
      <div class="setting-panel">
        <div class="panel-header">
          <p class="panel-title">运行资源</p>
          <el-button
            style=" padding: 3px 0"
            icon="el-icon-plus"
            type="text"
            @click="dialogVisible = true"
          ></el-button>
        </div>
        <el-card>
          <div class="files-wrapper">
            <div v-for="(file, index) in files" :key="index" class="files-item">
              <el-row :gutter="4" style="display: flex; align-items: center;">
                <el-col :span="23">
                  <span>{{ file }}</span>
                </el-col>
                <el-col :span="1">
                  <el-button
                    icon="el-icon-delete"
                    type="text"
                    @click="deleteFiles(index)"
                  ></el-button>
                </el-col>
              </el-row>
            </div>
          </div>
        </el-card>
      </div>
    </template>
    <template v-if="task.operator == 'DATAFACTORY'">
      <!-- 任务资源 -->
      <div class="setting-panel clearfix">
        <div class="panel-header">
          <p class="panel-title">任务资源</p>
        </div>
        <el-card>
          <el-form label-position="right" label-width="120px" >
            <el-form-item label="diver">
              <el-select v-model="sparkArgs.driver" placeholder="请选择diver">
                <el-option
                  v-for="item in driverOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="executor">
              <el-select v-model="sparkArgs.executor" placeholder="请选择executor">
                <el-option
                  v-for="item in executorOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="executor 个数">
              <el-input-number v-model="sparkArgs.numExecutors" :min="1" :max="30"></el-input-number>
            </el-form-item>
            <div class="table-box">
              <p class="panel-subtitle">配置 sparkConf</p>
              <div class="form-table">
                <div class="table-header table-tr">
                  <p class="tr-cell tr-left">参数名</p>
                  <p class="tr-cell tr-center">值</p>
                  <p class="tr-cell tr-right" v-show="sparkConf.length > 1">操作</p>
                </div>
                <div class="table-tr" v-for="(field, index) in sparkConf" :key="index">
                  <el-input class="tr-cell tr-left" v-model="field.key" placeholder="请输入参数名" @input="changeField"></el-input>
                  <el-input class="tr-cell tr-left" v-model="field.value" placeholder="请输入值" @input="changeField"></el-input>
                  <i v-show="sparkConf.length > 1" class="el-icon-circle-close tr-cell tr-right tr-icon" @click="deletField(index)"></i>
                </div>
              </div>
              <p class="error-msg">{{errMsg}}</p>
              <span class="add-tr" @click="addField"><i class="el-icon-circle-plus-outline"></i> 添加 sparkConf</span>
            </div>
          </el-form>
        </el-card>
      </div>
      <!-- 配置参数 -->
      <div class="setting-panel clearfix">
        <div class="panel-header">
          <p class="panel-title">配置参数</p>
        </div>
        <el-card>
          <el-form label-position="right" label-width="120px">
            <el-form-item label="运行环境">
              <el-select v-model="envId" placeholder="请选择运行环境">
                <el-option
                  v-for="item in envOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id">
                </el-option>
              </el-select>
            </el-form-item>
          </el-form>
        </el-card>
      </div>
    </template>
    <template v-else>
      <!-- 配置参数 -->
      <div class="setting-panel clearfix">
        <div class="panel-header">
          <p class="panel-title">配置参数</p>
        </div>
        <el-card>
          <el-form label-position="left" label-width="120px">
            <div class="config-wrapper">
              <div class="config-item">
                <el-form-item label="日期格式">
                  <el-input v-model="date_format"></el-input>
                </el-form-item>
              </div>
              <template v-if="!isDagRun">
                <div v-if="task.operator === 'SPARK'" class="config-item">
                  <el-form-item label="Spark 版本">
                    <el-select
                      v-model="version"
                      placeholder="请选择 Spark 版本"
                      clearable
                      style="width: 100%"
                    >
                      <el-option
                        v-for="version in versionOptions"
                        :key="version"
                        :label="version"
                        :value="version"
                      >
                      </el-option>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="PySpark 环境">
                    <el-select
                      v-model="pyspark"
                      placeholder="请选择 PySpark 环境"
                      clearable
                      style="width: 100%"
                    >
                      <el-option
                        v-for="pyspark in pysparkOptions"
                        :key="pyspark"
                        :label="pyspark"
                        :value="pyspark"
                      >
                      </el-option>
                    </el-select>
                  </el-form-item>
                </div>
              </template>
              <div v-else class="config-item">
                <el-form-item label="项目" required>
                  <el-select
                    v-model="projectid"
                    placeholder="请选择项目"
                    clearable
                    @change="projectChange"
                  >
                    <el-option
                      v-for="project in projectOptions"
                      :key="project.id"
                      :label="project.name"
                      :value="project.id"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="工作流" required>
                  <el-select v-model="workflowid" placeholder="请选择工作流" clearable>
                    <el-option
                      v-for="item in workflowOptions"
                      :key="item.id"
                      :label="item.name"
                      :value="item.id"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </div>
            </div>
          </el-form>
        </el-card>
      </div>
    </template>
    <!-- 运行资源弹框 -->
    <el-dialog :visible.sync="dialogVisible" title="运行资源" append-to-body width="50%">
        <el-breadcrumb slot="title" separator="/">
          <el-breadcrumb-item v-for="(item, index) in selected" :key="index">
            <el-link type="primary">{{ item }}</el-link>
          </el-breadcrumb-item>
        </el-breadcrumb>
        <div class="query-area">
          <el-input v-model="query" placeholder="请输入内容" @change="queryFiles">
            <el-button slot="append" icon="el-icon-search" @click="queryFiles"></el-button>
          </el-input>
        </div>

        <div class="data-area">
          <el-table :data="fileList" size="small">
            <el-table-column prop="file_name" label="Name">
              <template slot-scope="scope">
                <el-link type="primary" @click="fileClickHandler(scope.row)">{{
                  scope.row.file_name
                }}</el-link>
              </template>
            </el-table-column>
            <el-table-column prop="size" label="Size" width="80"></el-table-column>
            <el-table-column prop="last_modified" label="Last Modified" width="180"></el-table-column>
          </el-table>
        </div>
        <div slot="footer" class="dialog-footer"></div>
      </el-dialog>
  </div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
import { Promise } from 'q';
export default {
  name: "TaskSettingBase",
  props: {
    id: String
  },
  data() {
    return {
      task: {},
      OP_OPTIONS: [],
      dialogVisible: false,
      query: "",
      selected: [],
      fileList: [],
      configList: [
        {
          key: "",
          value: ""
        }
      ],
      files: [],
      projectid: "",
      workflowid: "",
      projectOptions: [],
      workflowOptions: [],
      pysparkOptions: ["python3.9", "python3.10"],
      flinkRetryOptions:[
         {
          value: 5,
          label: '5次/半小时'
        },
        {
          value: 9999999,
          label: '无限'
        }
      ],
      versionOptions: ["3.2"],
      version: "3.2",
      pyspark: "",
      date_format: "",
      sparkArgs: {
        sparkConf: [],
        driver: '',
        driverCores: 1,
        driverMemory: "1g",
        numExecutors: 1,
        executor: '',
        executorCores: 1,
        executorMemory: "1g"
      },
      isStreaming: '',
      envId: '',
      isMetricsMonitor: false,
      envOptions: [],
      executorOptions: [],
      driverOptions: [],
      nodeParam: {},
      errMsg: '',
      sparkConf: [
        {
          key: '',
          value: ''
        }
      ]
    };
  },
  computed: {
    ...mapState({
      currentTab: ({ data }) => data.currentTab
    }),
    isDagRun() {
      let { operator } = this.task;
      return operator === "DAGRUN";
    },
    needFile() {
      let isCustom = this.currentTab.param && this.currentTab.param.filterModel && this.currentTab.param.filterModel.type == 2 ? true : false
      let noDF = this.currentTab.operator == 'DATAFACTORY' ? false : true
      return noDF || isCustom
    }
  },
  watch: {
    dialogVisible: {
      handler(val) {
        if (val) {
          const {project_id = ''} = this.$route.query
          this.selected.push(project_id + "\/");
          this.queryFiles();
        } else {
          this.selected = [];
        }
      },
      immediate: true
    }
  },
  mounted() {},

  created() {
    this.initData();
  },
  methods: {
    ...mapMutations(["setCurrentTab"]),
    projectChange(project) {
      this.workflowid = "";
      if (!project) {
        this.workflowOptions = [];
        return;
      }
      this.$http.workflow.getWorkflowOptions({ project_id: project }).then(res => {
        this.workflowOptions = res;
      });
    },
    initData() {
      this.$http.task.getTaskTypes().then(res => {
        this.OP_OPTIONS = res;
      });

      this.$http.workflow.getProjectOptions().then(res => {
        this.projectOptions = res;
      });
      this.getDFoptions()
      this.$http.task.getTaskById({ id: this.id }).then(res => {
        this.task = res;
        this.files = this.task.files ? this.task.files.split(",") : [];
        if(res.operator == "FLINK"){
          if(res.retries < 5){
            this.task.retries = 5
          }else {
            this.task.retries = res.retries
          }
        }
        if (this.task.param) {
          // param 对象转换为 key：value 形式的对象数组( {a: 1, b: 2} => [{key: 'a',value: '1'},{key: 'b',value: '2'}] )
          if (this.task.operator !== "DAGRUN") {
            let arry = [];
            Object.keys(this.task.param).forEach(key => {
              if (key === "version" || key === "pyspark") {
                this[key] = this.task.param[key];
              } else {
                arry.push({ key, value: this.task.param[key] });
              }
            });
            this.configList = arry;
          } else {
            this.workflowid = this.task.param["workflow_id"];
            this.projectid = this.task.param["project_id"];

            this.$http.workflow.getWorkflowOptions({ project_id: this.projectid }).then(res => {
              this.workflowOptions = res;
            });
          }

          this.date_format = this.task.param["date_format"];
          // DATAFACTORY param 初始化赋值
          if(res.operator == 'DATAFACTORY') {
            const {sparkArgs = {}, isStreaming = true, isMetricsMonitor = false, envId = 1, writerModel = {}, filterModel = {}, readerModel = {}} = res.param
            const  {driverCores = 1, driverMemory = '1g', executorCores = 1, executorMemory = '1g', sparkConf = []} = sparkArgs
            const driver = driverCores + '核-' + driverMemory
            const executor = executorCores + '核-' + executorMemory
            this.sparkArgs = {
              ...sparkArgs,
              driver,
              executor
            }
            const arr = [{
              key: '',
              value: ''
            }]
            this.sparkConf = sparkConf.length > 0 ? sparkConf : arr
            this.isStreaming = isStreaming
            this.isMetricsMonitor = isMetricsMonitor
            this.envId = envId
            this.nodeParam = {
              writerModel,
              filterModel,
              readerModel
            }
          }
        }
      });
    },
    // 获取DATAFACTORY需要的options
    getDFoptions() {
      this.$http.task.envs().then(res => {
        this.envOptions = res
      })
      this.$http.task.run_resource().then( res => {
        this.driverOptions = res.driver_options
        this.executorOptions = res.executor_options
      })
    },
    // 加载资源信息列表
    queryFiles() {
      let path = this.selected.join("") + this.query;
      this.$http.file.getFilesByPath({ path }).then(res => {
        this.fileList = res;
      });
    },
    // 单击选中
    fileClickHandler(file) {
      let { is_dir, file_name } = file;
      this.selected.push(file_name);
      if (is_dir) {
        this.query = "";
        this.queryFiles();
      } else {
        this.confirmSelected();
      }
    },
    // 确认选中
    confirmSelected() {
      this.dialogVisible = false;
      this.files.push(this.selected.join(""));
    },
    // addConfig() {
    //   this.configList.push({
    //     key: "",
    //     value: ""
    //   });
    // },
    deleteConfig(index) {
      this.configList.splice(index, 1);
    },
    deleteFiles(index) {
      this.files.splice(index, 1);
    },
    // sparkConf
    changeField() {
      this.errMsg = ''
    },
    deletField(index) {
      this.errMsg = ''
      this.sparkConf.splice(index, 1)
    },
    addField() {
      let obj = {
        key: '',
        value: ''
      }
      this.sparkConf.push(obj)
      this.errMsg = ''
    },
    // 设置保存
    save() {
      let { isDagRun, configList, workflowid, projectid } = this;

      let param = {};
      
      if(this.task.operator == 'DATAFACTORY') {
        const {driver, numExecutors, executor} = this.sparkArgs
        const  [driverCores, driverMemory] = driver.split('核-');
        const [executorCores, executorMemory] = executor.split('核-');
        let sparkArgs = {
          sparkConf: this.sparkConf,
          numExecutors,
          driverCores,
          driverMemory,
          executorCores,
          executorMemory
        }
        param["sparkArgs"] = sparkArgs;
        param["isStreaming"] = true
        param['isMetricsMonitor'] = this.isMetricsMonitor
        param['envId'] = this.envId
        param = {
          ...param,
          ...this.nodeParam
        }
      } else {
        if (isDagRun) {
          let msg = [];
          if (!projectid) {
            msg.push("项目");
          }
          if (!workflowid) {
            msg.push("工作流");
          }

          if (msg && msg.length) {
            this.$message({
              type: "warning",
              message: msg.join("、") + "为必填项"
            });
            return;
          }

          param["project_id"] = projectid;
          param["workflow_id"] = workflowid;
        } else {
          configList.forEach(config => {
            if (config.key) param[config.key] = config.value;
          });

          param["version"] = this.version;
          param["pyspark"] = this.pyspark;
        }

        param["date_format"] = this.date_format;       
      }
      this.task.files = this.files.join(",");
      this.task.param = param;
      this.$http.task.updateTask(this.task).then(res => {
        if(this.task.operator == 'DATAFACTORY') {
          let curContent = {
            ...this.currentTab,
            param: this.task.param,
          }
          this.setCurrentTab(curContent)
        }
        this.$message({
          type: "success",
          message: "保存成功"
        });
      });
    }
  }
};
</script>
<style lang="scss">
$border-color: #e4e7ed;
$border: 1px solid $border-color;
.base-setting {
  height: calc(100vh - 120px);
  overflow: auto;
}
.config-item + .config-item {
  margin-top: 8px;
}
.panel-title{
  line-height: 14px;
  font-size: 14px;
  font-weight: bold;
  padding: 0 10px;
  border-left: 3px solid #409eff;
}
.panel-subtitle{
  line-height: 14px;
  font-size: 14px;
  font-weight: bold;
  color: #666;
} 
.table-box{
  // display: flex;
  // align-items: flex-end;
  border-top: $border;
  .form-table{
    // flex: 1;
    border-top: $border;
    border-left: $border;
    border-right: $border;
    .table-header {
      background: #f8f8f9;
      line-height: 40px;
      font-size: 14px;
      font-weight: bold;
      color: #515a6e;
      p{
        padding: 0;
        margin: 0;
      }
    }
    .table-tr{
      display: flex;
      align-items: center;
      border-bottom: $border;
      // height: 40px;
    }
    .tr-cell{
      text-align: center;
    }
    .tr-left, .tr-center{
      flex: 1;
      border-right: $border;
      padding: 10px;
    }
    .tr-right{
      width: 60px;
    }
  }
  .tr-icon{
    font-size: 24px;
    color: #999;
    cursor: pointer;
    &:hover{
      color: #409eff;
    }
  }
  .error-msg{
    color: #F56C6C;
  }
  .add-tr{
    font-size: 14px;
    color: #409eff;
    cursor: pointer;
  }
}

</style>
